using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

using SIMA.Entities;
using SIMA.Core.Data.Collection;
using SIMA.Core.Data.Access;
using SIMA.Core.Enums;
using SIMA.Core.EventArgs;
using SIMA.Core.Security;

namespace SIMA.Services
{

	public class T_C_TrabajoService : IT_C_TrabajoService
	{
		#region Fields

		private SmartContainer<T_C_Trabajo> dataAccessSmart;
		private FailedEventArgs onFailed;
		private InsertedEventArgs onInserted;
		private UpdatedEventArgs onUpdated;
		private DeletedEventArgs onDeleted;
		private static Semaphore ResourceLock;
        private FilterType filter;
        private T_C_Trabajo tmpTrabajo1, tmpTrabajo2;

		#endregion

		#region Constructor

		public T_C_TrabajoService()
		{
			DataAccess.SetConnection(SIMA.Core.Enums.AccessType.FromString, "Data Source=.;Initial Catalog=SIMA;Integrated Security=True");
			ResourceLock = new Semaphore(0, 2);
			dataAccessSmart = new SmartContainer<T_C_Trabajo>(false,true);
			dataAccessSmart.Inserted += new EventHandler<InsertedEventArgs>(dataAccessSmart_Inserted);
			dataAccessSmart.Failed += new EventHandler<FailedEventArgs>(dataAccessSmart_Failed);
			dataAccessSmart.Updated += new EventHandler<UpdatedEventArgs>(dataAccessSmart_Updated);
			dataAccessSmart.Deleted += new EventHandler<DeletedEventArgs>(dataAccessSmart_Deleted);
		}

		#endregion

		#region Implementacion de eventos del SmartContainer

        private void dataAccessSmart_Inserted(object sender, InsertedEventArgs e)
        {
            onInserted = e;
        }

        private void dataAccessSmart_Updated(object sender, UpdatedEventArgs e)
        {
            onUpdated = e;
        }

        private void dataAccessSmart_Deleted(object sender, DeletedEventArgs e)
        {
            onDeleted = e;
        }

        private void dataAccessSmart_Failed(object sender, FailedEventArgs e)
        {
            onFailed = e;
        }

		#endregion

		#region Implementando la interfaz de servicio

		public List<T_C_Trabajo> GetAllT_C_Trabajo(Profile securityProfile)
		{
			SecurityProgram.PcProfile = securityProfile;
			dataAccessSmart.SelectAll();
			return dataAccessSmart.ToList();
		}

		public IAsyncResult BeginGetAllT_C_Trabajo(Profile securityProfile, AsyncCallback callback, object state)
		{
			T_C_TrabajoAsyncResult asyncResult = new T_C_TrabajoAsyncResult(securityProfile, callback, state);
			ThreadPool.QueueUserWorkItem(new WaitCallback((GetAllT_C_TrabajoCallback)), asyncResult);
			return asyncResult;
		}

		private void GetAllT_C_TrabajoCallback(object asyncResult)
		{
			T_C_TrabajoAsyncResult getT_C_TrabajoAsyncResult = (T_C_TrabajoAsyncResult)asyncResult;
			try
			{
				getT_C_TrabajoAsyncResult.CollectionResult = GetAllT_C_Trabajo(SecurityProgram.PcProfile);
				getT_C_TrabajoAsyncResult.ExceptionTrace = null;
				getT_C_TrabajoAsyncResult.MessageResult = string.Empty;
			}
			catch(Exception ex)
			{
				getT_C_TrabajoAsyncResult.CollectionResult = null;
				getT_C_TrabajoAsyncResult.ExceptionTrace = ex;
				getT_C_TrabajoAsyncResult.MessageResult = string.Empty;
			}
			finally
			{
				getT_C_TrabajoAsyncResult.OnCompleted();
			}
		}

		public List<T_C_Trabajo> EndGetAllT_C_Trabajo(IAsyncResult asyncResult)
		{
			List<T_C_Trabajo> lista = null;
			using(T_C_TrabajoAsyncResult getT_C_TrabajoResult = asyncResult as T_C_TrabajoAsyncResult)
			{
				getT_C_TrabajoResult.AsyncWaitHandle.WaitOne();
				lista = getT_C_TrabajoResult.CollectionResult;
			}
			return lista;
		}

	 public List<T_C_Trabajo> GetFilteredT_C_Trabajo(Profile securityProfile, FilterType filter)
        {
            List<T_C_Trabajo> lista = null;
            this.filter = filter;
            SecurityProgram.PcProfile = securityProfile;
            switch (filter)
            {
                case FilterType.Active:
                    lista = dataAccessSmart["SelectActiveTrabajo", CommandType.StoredProcedure];
                    break;
                case FilterType.Inactive:
                    lista = dataAccessSmart["SelectInactiveTrabajo", CommandType.StoredProcedure];
                    break;
            }
            return lista;
        }

        public IAsyncResult BeginGetFilteredT_C_Trabajo(Profile securityProfile, FilterType filter, AsyncCallback callback, object state)
        {
            T_C_TrabajoAsyncResult asyncResult = new T_C_TrabajoAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetFilteredT_C_TrabajoCallback)), asyncResult);
            return asyncResult;
        }

        private void GetFilteredT_C_TrabajoCallback(object asyncResult)
        {
            T_C_TrabajoAsyncResult getT_C_TrabajoAsyncResult = (T_C_TrabajoAsyncResult)asyncResult;
            try
            {
                getT_C_TrabajoAsyncResult.CollectionResult = GetFilteredT_C_Trabajo(SecurityProgram.PcProfile, this.filter);
                getT_C_TrabajoAsyncResult.ExceptionTrace = null;
                getT_C_TrabajoAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getT_C_TrabajoAsyncResult.CollectionResult = null;
                getT_C_TrabajoAsyncResult.ExceptionTrace = ex;
                getT_C_TrabajoAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getT_C_TrabajoAsyncResult.OnCompleted();
            }
        }
///
        public List<T_C_Trabajo> EndGetFilteredT_C_Trabajo(IAsyncResult asyncResult)
        {
            List<T_C_Trabajo> lista = null;
            using (T_C_TrabajoAsyncResult getT_C_TrabajoResult = asyncResult as T_C_TrabajoAsyncResult)
            {
                getT_C_TrabajoResult.AsyncWaitHandle.WaitOne();
                lista = getT_C_TrabajoResult.CollectionResult;
            }
            return lista;
        }

        #endregion

        #region New

        public string RegisterT_C_Trabajo(Profile securityProfile, T_C_Trabajo newItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTrabajo1 = newItem;
            dataAccessSmart.Add(newItem);
            ResourceLock.WaitOne(1000);
            return "Nuevo registro de Trabajo creado.";
        }

        public IAsyncResult BeginRegisterT_C_Trabajo(Profile securityProfile, T_C_Trabajo newItem, AsyncCallback callback, object state)
        {
            T_C_TrabajoAsyncResult asyncResult = new T_C_TrabajoAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((RegisterT_C_TrabajoCallback)), asyncResult);
            return asyncResult;
        }

        private void RegisterT_C_TrabajoCallback(object asyncResult)
        {
            T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = (T_C_TrabajoAsyncResult)asyncResult;
            try
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = null;
                t_c_TrabajoAsyncResult.MessageResult = RegisterT_C_Trabajo(SecurityProgram.PcProfile, tmpTrabajo1);

            }
            catch (Exception ex)
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = ex;
                t_c_TrabajoAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TrabajoAsyncResult.OnCompleted();
                tmpTrabajo1 = null;
            }
        }

        public string EndRegisterT_C_Trabajo(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = asyncResult as T_C_TrabajoAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TrabajoAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion

        #region Update

        public string UpdateT_C_Trabajo(Profile securityProfile, T_C_Trabajo itemToUpdate, T_C_Trabajo itemUpdated)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTrabajo1 = itemToUpdate;
            tmpTrabajo2 = itemUpdated;
            dataAccessSmart.Update(tmpTrabajo1, tmpTrabajo2);
            ResourceLock.WaitOne(1000);
            return "Cambio de Trabajo realizado.";
        }

        public IAsyncResult BeginUpdateT_C_Trabajo(Profile securityProfile, T_C_Trabajo itemToUpdate, T_C_Trabajo itemUpdated, AsyncCallback callback, object state)
        {
            T_C_TrabajoAsyncResult asyncResult = new T_C_TrabajoAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((UpdateT_C_TrabajoCallback)), asyncResult);
            return asyncResult;
        }

        private void UpdateT_C_TrabajoCallback(object asyncResult)
        {
            T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = (T_C_TrabajoAsyncResult)asyncResult;
            try
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = null;
                t_c_TrabajoAsyncResult.MessageResult = UpdateT_C_Trabajo(SecurityProgram.PcProfile, tmpTrabajo1, tmpTrabajo2);

            }
            catch (Exception ex)
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = ex;
                t_c_TrabajoAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TrabajoAsyncResult.OnCompleted();
                tmpTrabajo1 = null;
                tmpTrabajo2 = null;
            }
        }

        public string EndUpdateT_C_Trabajo(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = asyncResult as T_C_TrabajoAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TrabajoAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion

        #region Delete

        public string DeleteT_C_Trabajo(Profile securityProfile, T_C_Trabajo dropItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTrabajo1 = dropItem;
            dataAccessSmart.Remove(dropItem);
            ResourceLock.WaitOne(1000);
            return "Baja de trabajo realizado.";
        }

        public IAsyncResult BeginDeleteT_C_Trabajo(Profile securityProfile, T_C_Trabajo dropItem, AsyncCallback callback, object state)
        {
            T_C_TrabajoAsyncResult asyncResult = new T_C_TrabajoAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((DeleteT_C_TrabajoCallback)), asyncResult);
            return asyncResult;
        }

        private void DeleteT_C_TrabajoCallback(object asyncResult)
        {
            T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = (T_C_TrabajoAsyncResult)asyncResult;
            try
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = null;
                t_c_TrabajoAsyncResult.MessageResult = DeleteT_C_Trabajo(SecurityProgram.PcProfile, tmpTrabajo1);

            }
            catch (Exception ex)
            {
                t_c_TrabajoAsyncResult.CollectionResult = null;
                t_c_TrabajoAsyncResult.ExceptionTrace = ex;
                t_c_TrabajoAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TrabajoAsyncResult.OnCompleted();
                tmpTrabajo1 = null;
            }
        }

        public string EndDeleteT_C_Trabajo(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TrabajoAsyncResult t_c_TrabajoAsyncResult = asyncResult as T_C_TrabajoAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TrabajoAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion    

		
	}
}
